<template>
  <uploader
    :options="options"
    class="uploader-example"
    ref="uploader"
    :autoStart="true"
    @file-added="onFileAdded"
    @file-success="onFileSuccess"
    @file-progress="onFileProgress"
    @file-error="onFileError"
    :accept="'image/*'"
  >
    <uploader-unsupport></uploader-unsupport>
    <uploader-drop>
      <p>Drop files here to upload or</p>
      <uploader-btn>select files</uploader-btn>
      <!-- <uploader-btn :attrs="attrs">select images</uploader-btn>
      <uploader-btn :directory="true">select folder</uploader-btn>-->
    </uploader-drop>
    <uploader-list></uploader-list>
  </uploader>
</template>

<script>
export default {
  data() {
    return {
      options: {
        // https://github.com/simple-uploader/Uploader/tree/develop/samples/Node.js
        target: this.$host + '/api/UploadFile',
        testChunks: false,
      },
      attrs: {
        accept: 'pdf/*',
      },
      panelShow: false,
    }
  },
  props: {
    fileType: {
      type: String,
      default: '',
    },
  },
  methods: {
    onFileSuccess(rootFile, file, response, chunk) {
      let res = JSON.parse(response)
      console.log('res :>> ', res)

      // 服务器自定义的错误，这种错误是Uploader无法拦截的
      if (res.code !== 0) {
        this.$message.error(res.description)
        return
      }

      // 如果服务端返回需要合并
      if (res.needMerge) {
        api
          .mergeSimpleUpload({
            tempName: res.tempName,
            fileName: file.name,
            ...this.params,
          })
          .then((data) => {
            // 文件合并成功
            Bus.$emit('fileSuccess', data)
          })
          .catch((e) => {})
        // 不需要合并
      } else {
        this.$emit('fileSuccess', res)
        console.log('上传成功')
      }
    },

    onFileError(rootFile, file, response, chunk) {
      console.log(error)
    },
    // 文件进度的回调
    onFileProgress(rootFile, file, chunk) {
      console.log(
        `上传中 ${file.name}，chunk：${chunk.startByte / 1024 / 1024} ~ ${
          chunk.endByte / 1024 / 1024
        }`
      )
    },
    onFileAdded(file) {
      this.panelShow = true
      //   file.pause()

      // 计算MD5，下文会提到
      //   this.computeMD5(file)
    },
    /**
     * 计算md5，实现断点续传及秒传
     * @param file
     */
    /**
     * 计算md5，实现断点续传及秒传
     * @param file
     */
    computeMD5(file) {
      let fileReader = new FileReader()
      let time = new Date().getTime()
      let blobSlice =
        File.prototype.slice ||
        File.prototype.mozSlice ||
        File.prototype.webkitSlice
      let currentChunk = 0
      const chunkSize = 10 * 1024 * 1000
      let chunks = Math.ceil(file.size / chunkSize)
      let spark = new SparkMD5.ArrayBuffer()

      // 文件状态设为"计算MD5"
      this.statusSet(file.id, 'md5')

      file.pause()

      loadNext()

      fileReader.onload = (e) => {
        spark.append(e.target.result)
        if (currentChunk < chunks) {
          currentChunk++
          loadNext()
          // 实时展示MD5的计算进度
          this.$nextTick(() => {
            $(`.myStatus_${file.id}`).text(
              '校验MD5 ' + ((currentChunk / chunks) * 100).toFixed(0) + '%'
            )
          })
        } else {
          let md5 = spark.end()
          this.computeMD5Success(md5, file)
          console.log(
            `MD5计算完毕：${file.name} \nMD5：${md5} \n分片：${chunks} 大小:${
              file.size
            } 用时：${new Date().getTime() - time} ms`
          )
        }
      }
      fileReader.onerror = function () {
        this.error(`文件${file.name}读取出错，请检查该文件`)
        file.cancel()
      }
      function loadNext() {
        let start = currentChunk * chunkSize
        let end = start + chunkSize >= file.size ? file.size : start + chunkSize
        fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
      }
    },

    computeMD5Success(md5, file) {
      // 将自定义参数直接加载uploader实例的opts上
      Object.assign(this.uploader.opts, {
        query: {
          ...this.params,
        },
      })
      file.uniqueIdentifier = md5
      file.resume()
      this.statusRemove(file.id)
    },
    checkChunkUploadedByResponse(chunk, message) {
      let objMessage = JSON.parse(message)
      if (objMessage.skipUpload) {
        return true
      }

      return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0
    },
  },
}
</script>

<style lang="less" scoped>
// .uploader-example {
//   width: 880px;
//   padding: 15px;
//   margin: 40px auto 0;
//   font-size: 12px;
//   box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
// }
// .uploader-example .uploader-btn {
//   margin-right: 4px;
// }
// .uploader-example .uploader-list {
//   max-height: 440px;
//   overflow: auto;
//   overflow-x: hidden;
//   overflow-y: auto;
// }
</style>